package servlets;
import image.RandomCodeUtils;
import image.SecurityCodeImage;
import image.SecurityCodeImageFactory;
import image.SecurityCodeProperty;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
  

 @SuppressWarnings("serial")
public class SecurityCodeServlet extends HttpServlet { 
  
     /** 
      * 验证码图形参数 
      */ 
     private SecurityCodeProperty property = new SecurityCodeProperty(); 
     /** 
      * Session名 
      */ 
     private String sessionName = "securityCode"; 
     /** 
      * 验证码图像引擎 
      */ 
     private SecurityCodeImage securityCodeImage; 
     /** 
      * 日志 
      */ 
     private static final Log log = LogFactory.getLog(SecurityCodeServlet.class); 
  
     @Override 
     public void init() throws ServletException { 
         super.init(); 
         setProperty(); 
         securityCodeImage = SecurityCodeImageFactory.getSecurityCodeImage(property); 
     } 
  
     /**  
      * Handles the HTTP <code>GET</code> method. 
      * @param request servlet request 
      * @param response servlet response 
      * @throws ServletException if a servlet-specific error occurs 
      * @throws IOException if an I/O error occurs 
      * @since 0.2 
      */ 
     @Override 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) 
             throws ServletException, IOException { 
         exportSecurityCode(request, response); 
     } 
  
     /**  
      * Handles the HTTP <code>POST</code> method. 
      * @param request servlet request 
      * @param response servlet response 
      * @throws ServletException if a servlet-specific error occurs 
      * @throws IOException if an I/O error occurs 
      * @since 0.2 
      */ 
     @Override 
     protected void doPost(HttpServletRequest request, HttpServletResponse response) 
             throws ServletException, IOException { 
         exportSecurityCode(request, response); 
     } 
  
     /** 
      * 输出验证码 
      * @param request servlet request 
      * @param response servlet response 
      * @throws ServletException if a servlet-specific error occurs 
      * @throws IOException if an I/O error occurs 
      * @since 0.2 
      */ 
     protected void exportSecurityCode(HttpServletRequest request, HttpServletResponse response) 
             throws ServletException, IOException { 
         setHeader(response); 
         String securityCode = RandomCodeUtils.random(property.getCodeLength()); 
         request.getSession().setAttribute(sessionName, securityCode); 
         securityCodeImage.exportSecurityCode(securityCode, response.getOutputStream()); 
     } 
  
     /** 
      * 设定Http协议头 
      * @param response servlet response 
      * @since 0.2 
      */ 
     private void setHeader(HttpServletResponse response) { 
         response.setHeader("Pragma", "no-cache"); 
         response.setHeader("Cache-Control", "no-cache"); 
         response.setDateHeader("Expires", 0); 
         response.setContentType("image/" + property.getFormatName()); 
     } 
  
     /** 
      * 设定参数 
      * @since 0.2 
      */ 
     private void setProperty() { 
         //需要读取的参数数组 
         String params[] = {"width", "height", "codeLength", "formatName", "font", "interfering", "backgroundColor", "sessionName"}; 
         try { 
             //读取参数，非null则拷贝到参数对象中 
             for (String param : params) { 
                 String value = getInitParameter(param); 
                 if (StringUtils.isNotEmpty(value)) { 
                     BeanUtils.copyProperty(property, param, value); 
                 } 
             } 
         } catch (IllegalAccessException ex) { 
             log.error("验证码组件设定参数出错", ex); 
            
         } catch (InvocationTargetException ex) { 
             log.error(ex, ex); 
            
         } 
     } 
 } 
 